package manadvert

import (
	"dub/app/web/manadvert/advertdefine"
	"dub/common"
	"dub/config"
	"dub/define"
	"dub/define/grpcmodel"
	"dub/frame"
	"dub/secrec"
	"dub/utils"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/golang/protobuf/proto"
	"os"
)

type WebManAdvertCenterServer struct {
	wmaCfg  define.WebManAdvertCenterServerConfig //广告中心
	logCfg  define.LogConfig                      //日志配置
	regConn common.IConnector                     //与注册服务器连接
	log     *utils.Logger                         //日志对象
}

func (w *WebManAdvertCenterServer) Init(cfgPath string) {
	var err error
	w.wmaCfg, w.logCfg, err = config.GetWebManAdvertCenterServerConfig(cfgPath)
	if err != nil {
		fmt.Println(err)
		os.Exit(2)
	}

	//日志配置
	log := utils.NewLogger()
	log.SetConfig(w.logCfg)
	w.log = log

	//连接主服务器
	conn := frame.NewConnector()
	conn.CallBack = w.RegServiceCallBack
	w.regConn = conn
	err = w.regConn.Start(w.wmaCfg.RegAddr)
	if err != nil {
		log.Errorf("server.go Init method w.regCon.Start err %v\n", err)
		os.Exit(2)
	}
	w.Reg()
	log.Infof("reg %s server is %s", w.logCfg.DeviceName, w.wmaCfg.Addr)

	//启动自己的http服务器
	//辅助设置
	advertdefine.Lobby_Login_Url = w.wmaCfg.LobbyLoginUrl
	advertdefine.Proxy_Url = w.wmaCfg.ProxyUrl
	advertdefine.WebUploadDir = w.wmaCfg.WebUploadDir
	//设定基础的配置
	beego.BConfig.WebConfig.ViewsPath = w.wmaCfg.WebWiew
	beego.SetStaticPath(w.wmaCfg.WebStaticUrl, w.wmaCfg.WebStaticPath)
	beego.BConfig.WebConfig.Session.SessionOn = true
	//如果想让session共享把所有的SessionProvider与SessionProviderConfig配置为一个地方，前提是在同一台服务器上
	//内存方式实现不了共享
	beego.BConfig.WebConfig.Session.SessionProvider = w.wmaCfg.SessionProvider
	beego.BConfig.WebConfig.Session.SessionProviderConfig = w.wmaCfg.SessionProviderConfig
	if w.wmaCfg.SessionProvider != "memory" {
		RegSessionGobStruct()
	}

	beego.BConfig.RunMode = w.wmaCfg.RunMode

	//日志设定
	beego.SetLogger("file", fmt.Sprintf(`{"filename":"./log/%s.log"}`, w.logCfg.DeviceName))
	//路由设定
	RouteAdd()
	//模板函数设置
	AddFunMap()
	//启动
	beego.Run(w.wmaCfg.Addr)
}

//注册服务器
func (w *WebManAdvertCenterServer) Reg() {
	serverInfo := &grpcmodel.ModelRegReqServerType{
		Addr:       w.wmaCfg.Addr,
		ServerName: define.ServerNameWeb_ManAdvertServer,
		ServerType: 2,
		ProxyUrl:   w.wmaCfg.ProxyUrl,
	}

	for {
		data, err := proto.Marshal(serverInfo)
		if err != nil {
			w.log.Errorf("server.go reg method proto.Marshal(serverInfo) err %v\n", err)
			continue
		}

		//发送注册命令
		err = w.regConn.Send(define.CmdRegServer_Register, define.CmdSubRegServer_Register_Reg, data)
		if err != nil {
			w.log.Errorf("server.go reg method w.regConn.Send(define.CmdRegServer_Register %d, define.CmdSubRegServer_Register_Reg %d, data) err %v\n", define.CmdRegServer_Register, define.CmdSubRegServer_Register_Reg, err)
			continue
		}
		break
	}
}

//注册服务回调函数
func (w *WebManAdvertCenterServer) RegServiceCallBack(mainId, subId uint16, data []byte) bool {
	if mainId == define.CmdRegServer_Register {
		switch subId {
		case define.CmdSubRegServer_Register_Reg_Inform:
			//下层服务上线通知
			res := &grpcmodel.ModelRegReqServerType{}
			err := proto.Unmarshal(data, res)
			if err != nil {
				w.log.Errorf("server.go RegServiceCallBack(%d, %d, data []byte) proto.Unmarshal(data,res) err %v\n", mainId, subId, err)
				return true
			}
			w.log.Infof("Reg_Inform is %+v	\n", res)

			//判断是否是逻辑服务
			if res.ServerType == 1 {
				protocol := "tcp"
				tmp_rpc := utils.NewRpcProxy(protocol, res.Addr)
				err := tmp_rpc.Start()
				if err != nil {
					w.log.Errorf("server.go RegServiceCallBack method s.dbRpc.Start method err %v\n", err)
					return true
				}

				//配置rpc服务
				switch res.ServerName {
				case define.ServerNameService_UseServer:
					secrec.AddSecRpc(secrec.ConstServiceUseRpc, tmp_rpc)
				}
			}
		case define.CmdSubRegServer_Register_Reg:
			res := &grpcmodel.ModelRegResServerType{}
			err := proto.Unmarshal(data, res)
			if err != nil {
				w.log.Errorf("server.go RegServiceCallBack(%d, %d, data []byte) proto.Unmarshal(data,res) err %v\n", mainId, subId, err)
				return true
			}

			if res.Err == 0 {
				w.log.Infoln("service web manadvert server reg success")
			} else {
				w.log.Infoln("service web manadvert server reg fail")
			}
		}
	}
	return true
}

var webManAdvertCenterServer *WebManAdvertCenterServer

func NewWebManAdvertCenterServer() *WebManAdvertCenterServer {
	if webManAdvertCenterServer == nil {
		webManAdvertCenterServer = new(WebManAdvertCenterServer)
	}
	return webManAdvertCenterServer
}
